fix: Update package vulnerability scanner to handle breaking PPM change#335
fix: Update package vulnerability scanner to handle breaking PPM change#335
Conversation
| async with httpx.AsyncClient() as client: | ||
| url = f"https://packagemanager.posit.co/__api__/repos/{repo}/vulns" | ||
| response = await client.get(url) | ||
| async with httpx.AsyncClient() as http: | ||
| url = "https://packagemanager.posit.co/__api__/filter/packages" | ||
| payload = { | ||
| "repo": repo, | ||
| "has_vulns": True, | ||
| "omit_downloads": True, | ||
| "omit_dependencies": True, | ||
| } |
There was a problem hiding this comment.
Is https://packagemanager.posit.co/__api__/filter/packages new or has it always been available? If it's new and we were using https://packagemanager.posit.co/__api__/repos/{repo}/vulns because it existed before the new one, then maybe we need to actually use the new one and if that doesn't work fall back to the old one?
There was a problem hiding this comment.
filter/packages is not that new (created in the 2024.11 release), but I'm not sure how that compares to when the code for the package vulnerability scanner was written.
I don't think we can fall back since https://packagemanager.posit.co/__api__/repos/{repo}/vulns doesn't exist anymore (unless I am overlooking something).
There was a problem hiding this comment.
I don't think we can fall back since
https://packagemanager.posit.co/__api__/repos/{repo}/vulnsdoesn't exist anymore (unless I am overlooking something).
This would be fallen back to if https://packagemanager.posit.co/__api__/filter/packages didn't (yet) exist or doesn't have the vulnerability params. The fallback is for users who might have a version of PPM that doesn't have filter/packages (or filter/packages doesn't yet accept the params we are sending).
@jstruzik do you know the history here? Is there a period of time where PPM's filter/packages doesn't support only returning vulnerable pacakges, but it did have repos/{repo}/vulns for that info?
There was a problem hiding this comment.
My assumption was based on the URL in the example app being hardcoded to point to the public Posit Package Manager, not a user's PPM instance. In the customer case where I encountered breaking it was because they were doing just that.
But in the case that someone has customized their package vulnerability scanner to point to their own PPM instance, I understand why the fallback would be relevant.
The has_vulns query param is indeed new to the April 9th 2026 release, but there was a vulns parameter that predated it, I'm not sure how far back.
There was a problem hiding this comment.
Ah right, sorry yeah if this is PPPM, it will be up to date, so that should be ok for the extension — maybe a comment in the code there about the release version and if someone is using this code against their own instance they might need to be more careful?
There was a problem hiding this comment.
@jonkeane ah sorry I missed this. There was a thread brought up about this change in https://positpbc.slack.com/archives/C6FBRF2V7/p1776098199483349
The tldr is that we removed the /repos/{repos}/vulns endpoint due to sizing constraints. We're actively discussing if https://github.com/rstudio/package-manager/issues/17690 makes sense to temporarily add back the functionality (perhaps with pagination or streaming)
The /filters/packages endpoint should have supported vulns for awhile now
| # This fetches vulnerabilities from the public Posit Package Manager, | ||
| # which is always up to date. If customizing this to reference your | ||
| # own PPM instance, note that the has_vulns parameter requires | ||
| # PPM 2026.04 or later. Older versions may need to use the vulns | ||
| # parameter instead, or the legacy endpoint: | ||
| # | ||
| # url = f"https://your-ppm-instance/__api__/repos/{repo}/vulns" | ||
| # response = await http.get(url) | ||
| # return repo, response.json() | ||
| # | ||
| # tasks = [fetch_repo_vulns(repo) for repo in repositories] | ||
| # for repo, data in await asyncio.gather(*tasks): | ||
| # results[repo] = data |
There was a problem hiding this comment.
@jonkeane What do you think about this as a solution to the other thread? I'm amendable to not leaving the old code and letting people sort that out on their own.
dotNomad
left a comment
There was a problem hiding this comment.
A quick check of the API docs shows that POST /__api__/filter/packages is utilizing a similar shape 👌
It looks like you are handling the newline-delimited JSON well here too.
|
I've held off on merging this because PPM looks like it will restore the old endpoint imminently. |
Should we though? Why wait? |
I guess I assumed it was inherently preferable to fetch from the original endpoint, otherwise we would have been grabbing from I think the difference is negligible since the length of the response of |
We handle the new PPM endpoint in the Package vulnerability scanner after
/repos/{repo}/vulnswas removed in favor of/filter/packages.https://packagemanager.posit.co/__docs__/news/package-manager/#breaking
To test this, deploy an app that imports one of the vulnerable packages, such as
beaker. The new scanner will display the vulnerability.(Note that when deploying with Publisher, you will need to build the frontend with
npm run buildand includedist/in the bundle.)You should see:

closes #334